public class ThreadDemo31MyBlockingQueue {
    private String[] data=null;

    //队首
    private int head;

    //队尾
    private  int tail;

    //元素个数
    private int size=0;

    public ThreadDemo31MyBlockingQueue(int capacity){
        data=new String[capacity];
    }

    public void put(String elem) throws InterruptedException{
        synchronized(this){
            while(size>=data.length){
                //队满，阻塞
                this.wait();
            }
            data[tail]=elem;
            tail++;
            if(tail>=data.length){
                tail=0;
            }
            size++;
            this.notify();
        }
    }

    public String take() throws InterruptedException{
        synchronized(this){
            while(size==0){
                //队空，阻塞
                this.wait();
            }
            String ret=data[head];
            head++;
            if(head>=data.length){
                head=0;
            }
            size--;
            this.notify();
            return ret;
        }
    }

    public static void main(String[] args) {
        ThreadDemo31MyBlockingQueue queue = new ThreadDemo31MyBlockingQueue(1000);

                Thread producer = new Thread(() -> {
                    int n = 0;
                    while (true) {
                        try {
                            queue.put(n + "");
                            System.out.println("生产元素 " + n);
                            n++;
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                });

                Thread consumer = new Thread(() -> {
                    while (true) {
                        String n = null;
                        try {
                            n = queue.take();
                            System.out.println("消费元素 " + n);
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                });

                producer.start();
                consumer.start();
            }

}
